#include "BbsControlData.h"
#include "Subs.h"
#include "Input.h"
#include "StringTable.h"
#include "Session.h"
#include "Users.h"
#include "Edit.h"
#include "OverlayManagement.h"

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <device.h>
#include <unistd.h>
#include <errno.h>
#include <cbm.h>
#include <time.h>
#include <ctype.h>

#pragma code-name("SUBSCODE");
#pragma rodata-name("SUBSCODE");
#pragma data-name("SUBSDATA");
#pragma bss-name("SUBSBSS");

char buffer[81];

void enterSubs(void)
{
	char c = 0;
	bool brk = false;

	if(!bcd.subsInitialized)
	{
		loadCurrents();
	}

	while(!brk)
	{
		if(c == 0) displayPrompt();
		c = tolower(inputChar(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), (inputOptions_t)(IO_ENTER | IO_ALPHA_NUMERIC)));

		switch(c)
		{
		case '?':
			outputCharacter(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), c);
			displayMenu();
			displayPrompt();
			break;
		case CH_ENTER:
			outputString(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), SUBS_READ_MESSAGE);
			readMessage(_currentSubboard.subboardNumber, _currentMsgThread.threadNumber, _currentSession.lastMessageNumber + 1);
			displayPrompt();
			break;
		case 'b':
			outputCharacter(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), c);
			listSubs();
			displayPrompt();
			break;
		case 't':
			outputCharacter(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), c);
			createThread();
			displayPrompt();
			break;
		case 'p':
			outputCharacter(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), c);
			createMessage(false);
			displayPrompt();
			break;
		case '*':
			outputCharacter(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), c);
			createMessage(true);
			displayPrompt();
			break;
		case '>':
			outputCharacter(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), c);
			loadThread(_currentMsgThread.threadNumber < _currentSubboard.highThreadNumber 
				? _currentMsgThread.threadNumber + 1 
				: _currentMsgThread.threadNumber, true, true);
			displayPrompt();
			break;
		case '<':
			outputCharacter(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), c);
			loadThread(_currentMsgThread.threadNumber > 1 
				? _currentMsgThread.threadNumber - 1 
				: 1, true, true);
			displayPrompt();
			break;
		case 'l':
			outputCharacter(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), c);
			listThreads();
			displayPrompt();
			break;
		case 'j':
			outputCharacter(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), c);
			chooseThread();
			displayPrompt();
			break;
		case 'r':
			outputCharacter(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), c);
			readMessageByNumber();
			displayPrompt();
			break;
		case 's':
			outputCharacter(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), c);
			gotoSubboard();
			displayPrompt();
			break;
		case 'n':
			outputCharacter(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), c);
			loadOverlay("bbs.new", &newMessageScan, "bbs.subs");
			displayPrompt();
			break;
		case 'k':
			outputCharacter(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), c);
			displayPrompt();
			// Find by keyword
			break;
		case 'd':
			outputCharacter(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), c);
			deleteCurrentMessage();
			displayPrompt();
			break;
		case 'q':
			outputCharacter(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), c);
			brk = true;
			break;
		}
	}
}

void displayMenu(void)
{
	outputFile(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), "subs.menu", &(bcd.dataDirectory));
}

void displayPrompt(void)
{
	//static char buffer[41];
	time_t time = _systime() + _baseTime;

	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), SUB_MENU_PROMPT_1);
	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), _currentSubboard.name);
	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), SUB_MENU_PROMPT_2);
	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), _currentMsgThread.topic);
	sprintf(buffer, SUB_MENU_PROMPT_3, _currentMsgThread.highMessageNumber == 0 ? 0 : 1, 
		_currentMsgThread.highMessageNumber);
	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), buffer);
	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), itoa(_currentSession.lastMessageNumber, buffer, 10));
	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), SUB_MENU_PROMPT_4);		
	strftime(buffer, 12, "%I:%M:%S %p", localtime(&time));
	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), buffer);
	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_SCREEN | OD_MODEM), SUB_MENU_PROMPT_5);		
}

void chooseThread(void)
{
	//static char buffer[6];
	static char string[41];
	static int threadNumber;

	sprintf(string, SUB_JUMP_PROMPT, _currentSubboard.lowThreadNumber, _currentSubboard.highThreadNumber);
	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), string);

	input(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), IO_NUMERIC, buffer, 5, false);

	threadNumber = atoi(buffer);

	if(threadNumber >= _currentSubboard.lowThreadNumber &&
		threadNumber <= _currentSubboard.highThreadNumber)
	{
		loadThread(threadNumber, true, true);
	}
	else
	{
		outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), SUB_JUMP_ERROR);
	}
}

void listThreads(void)
{
	int oldThread = _currentMsgThread.threadNumber;
	int curThread = 0;
	//char buffer[81];

	if(_currentSubboard.highThreadNumber == 0) return;
	if(_currentSubboard.lowThreadNumber == 0) return;

	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), CRLF CRLF);

	for(curThread = _currentSubboard.highThreadNumber; 
		curThread >= _currentSubboard.lowThreadNumber; 
		curThread--)
	{
		loadThread(curThread, false, false);
		if(_currentSession.requestedWidth > 40)
		{
			sprintf(buffer, CHX_GREEN "%5u " CHX_LGREEN "%-73s" CRLF, _currentMsgThread.threadNumber, _currentMsgThread.topic);
		}
		else
		{
			sprintf(buffer, CHX_GREEN "%5u " CHX_LGREEN "%-33s" CRLF, _currentMsgThread.threadNumber, _currentMsgThread.topic);
		}
		outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), buffer);
	}

	loadThread(oldThread, false, false);
}

void listSubs(void)
{
	static FILE *file;
	static char oldDirectory[17];
	static char directory[17];
	static char filename[17];
	static subIndexRec_t temp;
	static int i;
	static char buffer[81];

	getcwd(oldDirectory, 17);
	getdevicedir(bcd.dataDirectory.device, directory, 17);
	chdir(directory);

	sprintf(filename, "subsindex");
	file = fopen(filename, "rb");
	if(file != NULL)
	{
		outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), SUB_SUBSLIST_HEADER_1);
		outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), SUB_SUBSLIST_HEADER_2);

		if(fread(&_currentBases, sizeof(bases_t), 1, file))
		{
			for(i = 0; i < _currentBases.subboardCount; ++i)
			{
				if(fread(&temp, sizeof(subIndexRec_t), 1, file))
				{
					memset(buffer, 0, 81);
					if(_currentSession.requestedWidth < 80)
					{
						sprintf(buffer, SUB_SUBSLIST_ITEM_TMP4, temp.subboardNumber, temp.name, temp.description);
					}
					else
					{
						sprintf(buffer, SUB_SUBSLIST_ITEM_TMP8, temp.subboardNumber, temp.name, temp.description);
					}
					buffer[_currentSession.requestedWidth -1] = '\0';
					outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), buffer);
				}
			}
		}

		outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), CRLF);
		pause(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN));
		if(_connectState == CS_DISCONNECTED) return;
	}
	fclose(file);
	chdir(oldDirectory);
}

void loadThread(int threadNumber, bool loadIndexRecord, bool showIntro)
{
	static FILE *file;
	static char oldDirectory[17];
	static char directory[17];
	static char filename[17];

	file = NULL;

	if(threadNumber == _currentMsgThread.threadNumber) return;
	if(threadNumber < 1) return;
	if(threadNumber > _currentSubboard.highThreadNumber) return;

	memset(&_currentMsg, 0, sizeof(message_t));

	getcwd(oldDirectory, 17);
	getdevicedir(bcd.dataDirectory.device, directory, 17);
	chdir(directory);

	sprintf(filename, FILEPATTERN_THREAD, _currentSubboard.subboardNumber, threadNumber);
	file = fopen(filename, "rb");

	memset(&_currentMsgThread, 0, sizeof(msgThread_t));

	if(file != NULL)
	{
		if(fread(&_currentMsgThread, sizeof(msgThread_t), 1, file) == 1)
		//{
		//	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), CRLF CRLF CHX_RED "Could not read thread." CRLF);
		//}
		//else 
		{
			if(showIntro)
			{
				outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), SUBS_ENTERED_THREAD_1);
				outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), _currentMsgThread.topic);
				outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), SUBS_ENTERED_THREAD_2);
				outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), _currentMsgThread.startedByAlias);
			}

			if(loadIndexRecord)
			{
				fclose(file);
				memset(&_currentUserMsgIdx, 0, sizeof(userMsgIdxRec_t));
			
				sprintf(filename, FILEPATTERN_MSG_IDX_REC, _currentSubboard.subboardNumber, threadNumber, _currentUser.usernumber);
				file = fopen(filename, "rb");
				if(file != NULL &&
					fread(&_currentUserMsgIdx, sizeof(userMsgIdxRec_t), 1, file) != 1)
				{
					fclose(file);

					//outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), CRLF CRLF CHX_BROWN "Failed to read user msg idx record. ");
					//outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), itoa(_currentUserMsgIdx.lastMessageNumber, filename, 10));

					_currentUserMsgIdx.subboardNumber = _currentSubboard.subboardNumber;
					_currentUserMsgIdx.threadNumber = threadNumber;
					_currentUserMsgIdx.lastMessageNumber = 0;

					file = fopen(filename, "wb");
					if(file != NULL &&
						fwrite(&_currentUserMsgIdx, sizeof(userMsgIdxRec_t), 1, file) != 1)
					{
						//outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), "Could not write index record.");
					}
					fclose(file);

					_currentSession.lastMessageNumber = _currentUserMsgIdx.lastMessageNumber;
				}
				else if (file == NULL)
				{
					//outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), CRLF CRLF CHX_RED "Could not read user msg index record." CRLF);
					_currentUserMsgIdx.subboardNumber = _currentSubboard.subboardNumber;
					_currentUserMsgIdx.threadNumber = threadNumber;
					_currentUserMsgIdx.lastMessageNumber = 0; // _currentUserMsgIdx.lastMessageNumber;
				}
				fclose(file);

				_currentSession.lastMessageNumber = _currentUserMsgIdx.lastMessageNumber;
				_currentSession.lastThreadNumber = threadNumber;
			}
		}
		fclose(file);
	}
	//else
	//{
	//	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), CRLF CRLF CHX_RED "Could not open thread [");
	//	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), itoa(_errno, filename, 10));
	//	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), "]" CRLF);	
	//}

	fclose(file);
	chdir(oldDirectory);
}

void readMessage(int subboardId, unsigned int threadId, unsigned int messageId)
{
	static FILE *file;
	static char oldDirectory[17];
	static char directory[17];
	static char filename[17];
	static char timebuffer[31];
	//static char buffer[81];
	static user_t tempUser;
	static msgStatus_t msgStatus;
	static int c;

	getcwd(oldDirectory, 17);
	getdevicedir(bcd.dataDirectory.device, directory, 17);
	chdir(directory);

	sprintf(filename, FILEPATTERN_MSG, subboardId, threadId, messageId);

	file = fopen(filename, "rb");
	if(file != NULL)
	{
		if(fread(&_currentMsg, sizeof(message_t), 1, file))
		{
			if(fread(&msgStatus, sizeof(msgStatus_t), 1, file) != 1)
			{
				msgStatus.lastUpdatedBy = _currentMsg.postedByUsernumber;
				msgStatus.lastUpdatedOn = _currentMsg.postedOn;
				msgStatus.status = MS_NORMAL;
			}

			//fclose(file);

			_currentSession.lastMessageNumber = messageId;

			if(msgStatus.status == MS_NORMAL)
			{
				memset(timebuffer, 0, 31);
				strftime(timebuffer, 31, "%I:%M:%S %p %m/%d/%Y", localtime(&(_currentMsg.postedOn)));
				if(_currentMsg.responseToMessageNumber > 0)
				{
					loadUserByNumber(_currentMsg.respondingToUsernumber, &tempUser);
				}
				outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), SUBS_MSG_HEADER_1);
				loadUserByNumber(_currentMsg.postedByUsernumber, &tempUser);
				sprintf(buffer, SUBS_MSG_HEADER_2, tempUser.decorated_username);
				outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), buffer);
				sprintf(buffer, SUBS_MSG_HEADER_3, timebuffer);
				outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), buffer);
				sprintf(buffer, SUBS_MSG_HEADER_4, _currentMsg.subject);
				outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), buffer);
				//outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), SUBS_MSG_HEADER_5);
				if(_currentMsg.responseToMessageNumber > 0)
				{
					sprintf(buffer, SUBS_MSG_HEADER_6, tempUser.decorated_username);
					outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), buffer);
					sprintf(buffer, SUBS_MSG_HEADER_7, _currentMsg.responseToMessageNumber);
					outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), buffer);
				}
				outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), SUBS_MSG_HEADER_8);
				outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), CRLF CRLF);

				fclose(file);

				sprintf(filename, FILEPATTERN_MSG, subboardId, threadId, messageId);
				file = fopen(filename, "rb");
				memset(buffer, 0, 11);
				if(file != NULL
					&& fread(&_currentMsg, sizeof(message_t), 1, file)
					&& fread(&msgStatus, sizeof(msgStatus_t), 1, file))
				{
					while((c = fread(buffer, 1, 10, file)) > 0)
					{
						outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), buffer);
						memset(buffer, 0, 11);
					}
				}
				fclose(file);

				sprintf(filename, FILEPATTERN_MSG_IDX_REC, subboardId, threadId, _currentUser.usernumber);
				_currentUserMsgIdx.subboardNumber = subboardId;
				_currentUserMsgIdx.threadNumber = threadId;
				_currentUserMsgIdx.lastMessageNumber = messageId;
				_currentSession.lastMessageNumber = messageId;
				file = fopen(filename, "wb");
				if(file != NULL)
				{
					if(fwrite(&_currentUserMsgIdx, sizeof(userMsgIdxRec_t), 1, file))
					{
					}
				}
				fclose(file);
			}
			else
			{
				sprintf(buffer, SUBS_READ_MSG_DELETED, messageId);
				outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), buffer);

				_currentUserMsgIdx.subboardNumber = subboardId;
				_currentUserMsgIdx.threadNumber = threadId;
				_currentUserMsgIdx.lastMessageNumber = messageId;
				_currentSession.lastMessageNumber = messageId;
			}
		}
		else
		{
			fclose(file);
		}
	}

	fclose(file);
	chdir(oldDirectory);
}

bool saveMessage(message_t *message, char *body)
{
	return false;
}

void findByKeyword(char *keyword)
{
}

unsigned int getUnreadCount(void)
{
	return 0;
}

unsigned int getUnreadMessageCount(void)
{
	return 0;
}

void loadCurrents(void)
{
	static FILE *file;
	static char oldDirectory[17];
	static char directory[17];
	static char filename[17];
	//static char buffer[81];

	getcwd(oldDirectory, 17);
	getdevicedir(bcd.dataDirectory.device, directory, 17);
	chdir(directory);

	memset(&_currentBases, 0, sizeof(bases_t));
	memset(&_currentSubboard, 0, sizeof(subboard_t));
	memset(&_currentMsgThread, 0, sizeof(msgThread_t));
	memset(&_currentMsg, 0, sizeof(message_t));

	file = fopen("subsindex", "rb");

	if(file != NULL)
	{
		if(fread(&_currentBases, sizeof(bases_t), 1, file) == 1)
		{
			sprintf(buffer, SUB_NUMBER_SUBS, _currentBases.subboardCount);
			outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), buffer);

			fclose(file);

			if(_currentBases.subboardCount > 0)
			{
				file = fopen("sub-00000", "rb");

				if(file != NULL)
				{
					if(fread(&_currentSubboard, sizeof(subboard_t), 1, file) == 1)
					//{
					//	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), "Could not read first subboard.");
					//}
					//else
					{
						fclose(file);

						if(_currentSubboard.lowThreadNumber > 0)
						{
							loadThread(_currentSubboard.lowThreadNumber, true, true);
						}
						bcd.subsInitialized = true;
					}
				}
				//else
				//{
				//	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), "Could not open first subboard.");
				//}
			}
		}
		//else
		//{
		//	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), "Could not read bases.");
		//}
		fclose(file);
	}
	//else
	//{
	//	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), "Could not open subboard index.");
	//}


	chdir(oldDirectory);
}

void createThread(void)
{
	char threadTopic[71];
	static FILE *file;
	static char oldDirectory[17];
	static char directory[17];
	static char filename[17];
	//static char buffer[11];

	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), SUB_CREATE_THREAD);

	if(_currentSession.requestedWidth > 40)
	{
		input(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), IO_ALPHA_NUMERIC, threadTopic, 76, false);
	}
	else
	{
		input(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), IO_ALPHA_NUMERIC, threadTopic, 36, false);
	}

	if(strlen(threadTopic) == 0) 
	{
		outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), SUB_CREATE_THREAD_ABORT);
		return;
	}

	getcwd(oldDirectory, 17);
	getdevicedir(bcd.dataDirectory.device, directory, 17);
	chdir(directory);

	sprintf(filename, FILEPATTERN_THREAD, _currentSubboard.subboardNumber, _currentSubboard.highThreadNumber + 1);
	file = fopen(filename, "wb");

	if(file != NULL)
	{
		memset(&_currentMsgThread, 0, sizeof(msgThread_t));
		_currentMsgThread.threadNumber = _currentSubboard.highThreadNumber + 1;
		strcpy(_currentMsgThread.topic, threadTopic);
		_currentMsgThread.startedOn = _systime() + _baseTime;
		_currentMsgThread.startedByUsernumber = _currentUser.usernumber;
		strcpy(_currentMsgThread.startedByAlias, _currentUser.decorated_username);
		_currentMsgThread.isDeleted = false;
		_currentMsgThread.isLocked = false;

		if(fwrite(&_currentMsgThread, sizeof(msgThread_t), 1, file) == 1)
		{
			if(_currentMsgThread.threadNumber == 1 ||
				_currentSubboard.lowThreadNumber == 0)
			{
				_currentSubboard.lowThreadNumber = 1;
			}

			_currentSubboard.highThreadNumber = _currentMsgThread.threadNumber;

			sprintf(filename, FILEPATTERN_SUBBOARD, _currentSubboard.subboardNumber);

			fclose(file);

			file = fopen(filename, "wb");

			if(file != NULL)
			{
				if(fwrite(&_currentSubboard, sizeof(subboard_t), 1, file) != 1)
				{
					//outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), CRLF CHX_RED "Could not write subboard." CRLF);
				}
			}
			//else
			//{
			//	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), CRLF CHX_RED "Could not open subboard." CRLF);
			//}

			outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), SUB_CREATE_THREAD_2);

			_currentSession.lastMessageNumber = 0;
			_currentSession.lastSubboard = _currentMsgThread.threadNumber;
		}
		//else
		//{
		//	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), CRLF CHX_RED "Could not write thread." CRLF);
		//}

		fclose(file);
	}
	//else
	//{
	//	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), CRLF CHX_RED "Could not create thread." CRLF);
	//}

	chdir(oldDirectory);
}

void saveCurrentThread(void)
{
	char threadTopic[71];
	static FILE *file;
	static char oldDirectory[17];
	static char directory[17];
	static char filename[17];

	getcwd(oldDirectory, 17);
	getdevicedir(bcd.dataDirectory.device, directory, 17);
	chdir(directory);

	sprintf(filename, FILEPATTERN_THREAD, _currentSubboard.subboardNumber, _currentMsgThread.threadNumber);
	file = fopen(filename, "wb");

	if(file != NULL && 
		fwrite(&_currentMsgThread, sizeof(msgThread_t), 1, file) != 1)
	{
		//outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), CRLF CHX_RED "Could not write thread." CRLF);
	}

	fclose(file);

	chdir(oldDirectory);
}

void createMessage(bool reply)
{
	//static char buffer[81];
	static FILE *file;
	static char oldDirectory[17];
	static char directory[17];
	static char filename[17];
	static int originalPoster;
	static int originalMessageNumber;

	originalPoster = _currentMsg.postedByUsernumber;
	originalMessageNumber = _currentMsg.messageNumber;

	if(_currentMsgThread.threadNumber == 0)
	{
		outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), SUBS_NO_THREAD);
		return;
	}

	memset(&_currentMsg, 0, sizeof(message_t));
	memset(&_editInfo, 0, sizeof(editInfo_t));

	_currentMsg.messageNumber = _currentMsgThread.highMessageNumber + 1;
	_currentMsg.postedOn = _systime() + _baseTime;
	_currentMsg.postedByUsernumber = _currentUser.usernumber;

	if(reply)
	{
		_currentMsg.respondingToUsernumber = originalPoster;
		_currentMsg.responseToMessageNumber = originalMessageNumber;
	}

	if(_currentSubboard.subboardNumber == 0)
	{
		_currentMsg.isPrivate = true;
	}

	_currentMsg.originalEncoding = PLATFORM_ENCODING;

	sprintf(_editInfo.filename, FILEPATTERN_MSG_BODY, _currentSubboard.subboardNumber, _currentMsgThread.threadNumber, _currentMsg.messageNumber);
	_editInfo.message = &_currentMsg;

	//pause(PLATFORM_ENCODING, OD_SCREEN);

	loadOverlay("bbs.edit", &enterEditor, "bbs.subs");


}

void gotoSubboard(void)
{
	static char temp[5];
	static int subboardNumber;
	memset(temp, 0, sizeof(temp));
	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), SUB_GOTO_SUBBOARD);
	input(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), IO_NUMERIC, temp, 4, false);
	if(strlen(temp) > 0)
	{
		subboardNumber = atoi(temp);

		loadSubboard(subboardNumber);
	}
}

void loadSubboard(int subboardNumber)
{
	static FILE *file;
	static char oldDirectory[17];
	static char directory[17];
	static char filename[17];

	if(subboardNumber < 0 )
	{
		return;
	}

	_currentSession.lastSubboard = subboardNumber;

	getcwd(oldDirectory, 17);
	getdevicedir(bcd.dataDirectory.device, directory, 17);
	chdir(directory);
		
	sprintf(filename, FILEPATTERN_SUBBOARD, subboardNumber);
	file = fopen(filename, "rb");
	if(file != NULL)
	{
		if(fread(&_currentSubboard, sizeof(subboard_t), 1, file))
		{
			outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), SUBS_ENTER_SUBBOARD);
			outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), _currentSubboard.description);

			memset(&_currentMsgThread, 0, sizeof(msgThread_t));
			if(_currentSubboard.lowThreadNumber > 0)
			{
				loadThread(_currentSubboard.lowThreadNumber, true, true);
			}
			else
			{
				_currentSession.lastMessageNumber = 0;
				_currentSession.lastThreadNumber = 0;
			}
		}
	}

	fclose(file);
	chdir(oldDirectory);
}

void readMessageByNumber(void)
{
	static char temp[5];
	static int messageId;

	messageId = 0;
	memset(temp, 0, 5);

	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), SUBS_READ_MSG);
	input(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), IO_NUMERIC, temp, 4, false);

	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), CRLF);

	messageId = atoi(temp);

	if(messageId > 0 && messageId <= _currentMsgThread.highMessageNumber)
	{
		readMessage(_currentSubboard.subboardNumber, _currentMsgThread.threadNumber, messageId);
	}
}

void reply(void)
{
	createMessage(true);
}

void deleteCurrentMessage(void)
{
	static FILE *file;
	static char oldDirectory[17];
	static char directory[17];
	static char filename[17];
	static msgStatus_t status;
	//static char buffer[41];
	static char c;

	if(_currentMsg.postedByUsernumber != _currentUser.usernumber &&
		_currentUser.securityLevel < 90)
	{
		outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), SUBS_DELETE_NOT_ORIG_1);
		outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), SUBS_DELETE_NOT_ORIG_2);
		return;
	}
	
	sprintf(buffer, SUBS_DELETE_MESSAGE_1, _currentMsg.messageNumber);
	outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), buffer);

	while((c = tolower(inputChar(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), IO_ALPHA))) != 'n'
		&& c != 'y');

	outputCharacter(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), c);

	if(c == 'y')
	{
		status.lastUpdatedBy = _currentUser.usernumber;
		status.lastUpdatedOn = _systime() + _baseTime;
		status.status = MS_DELETED;

		getcwd(oldDirectory, 17);
		getdevicedir(bcd.dataDirectory.device, directory, 17);
		chdir(directory);
		
		sprintf(filename, FILEPATTERN_MSG, 
			_currentSubboard.subboardNumber,
			_currentMsgThread.threadNumber,
			_currentMsg.messageNumber);

		remove(filename);

		file = fopen(filename, "wb");
	
		if(file != NULL)
		{
			fwrite(&_currentMsg, sizeof(message_t), 1, file);
			fwrite(&status, sizeof(msgStatus_t), 1, file);
		}
	
		fclose(file);

		chdir(oldDirectory);

		sprintf(buffer, SUBS_DELETE_MESSAGE_2, _currentMsg.messageNumber);
		outputString(PLATFORM_ENCODING, (outDirections_t)(OD_MODEM | OD_SCREEN), buffer);
	}
}